package com.briup.cms.aop;

import com.briup.cms.bean.BaseLog;
import com.briup.cms.dao.BaseLogMapper;
import com.briup.cms.utils.UserInfo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;

/**
 * @Description  日志切面类： 向切入点添加日志记录功能,日志记录功能使用前置通知实现
 * @Author lining
 * @Date 2021/7/18 14:34
 * @Version 1.0.0
 */
@Aspect    //切面类
@Component  //ioc管理的对象
public class LogAspect {
    @Autowired
    private BaseLogMapper mapper;

    //1.提供切入点的规则 ： 哪些方法需要添加的日志记录功能？
    // 规则含义： 任意的web层的方法且使用了@Logging注解后添加日志记录功能
    @Pointcut("execution(* com.briup.cms.web.controller.*.*(..)) && @annotation(Logging)")
    public void logCutPoint(){
        // 切入点的名称就是方法名
        //记录web层中所有方法的开始执行的情况
    }
    //2.编写通知（编写代码增强的位置）： 前置通知  后置  环绕  异常
    @Before("logCutPoint()")
    public void BeforeAdvice(){
        //满足logCutPoint切入点的规则的方法会添加前置通知中的代码，执行方法开始前
        System.out.println("前置通知...");
        //1.通过工具类获取用户请求信息
        Map<String, Object> userInfo = UserInfo.getUserInfo();

        BaseLog baseLog = new BaseLog();
        //主键自增，不需要提供id值
        baseLog.setLogUsername((String) userInfo.get("username"));//用户名
        baseLog.setLogRealname((String) userInfo.get("realname"));// 昵称
        baseLog.setLogRequestMethod((String) userInfo.get("method"));//请求方法
        baseLog.setLogRequestUri((String) userInfo.get("uri"));//请求路径
        baseLog.setLogTime(new Date());
        //将日志记录信息对象保存到数据库中
        System.out.println("日志对象："+baseLog);
        mapper.insert(baseLog);
    }
    @After("logCutPoint()")
    public void AfterAdvice(){
        System.out.println("后置通知");
    }
    @Around("logCutPoint()")
    public Object aroudAdvice(ProceedingJoinPoint pjp){
        Object obj = null;
        System.out.println("环绕通知前...");
        try {
            obj = pjp.proceed();//表示调用目标对象中切入点方法
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("环绕通知后...");
        return obj;
    }
}
